#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
SQL智能纠错系统
提供词法、语法、语义分析阶段的错误检测和修复建议

实现功能：
1. 错误类型分类和识别
2. 智能修复建议生成
3. 相似度匹配和推荐
4. 上下文分析和错误定位
5. 多种修复策略
"""

from typing import Dict, List, Set, Tuple, Optional, Union, Any
from enum import Enum
import re
import difflib
from dataclasses import dataclass


class ErrorType(Enum):
    """错误类型枚举"""
    LEXICAL = "LEXICAL"           # 词法错误
    SYNTAX = "SYNTAX"             # 语法错误
    SEMANTIC = "SEMANTIC"         # 语义错误
    SPELLING = "SPELLING"         # 拼写错误
    MISSING_TOKEN = "MISSING_TOKEN"     # 缺少符号
    UNEXPECTED_TOKEN = "UNEXPECTED_TOKEN"   # 意外符号
    INVALID_IDENTIFIER = "INVALID_IDENTIFIER"   # 无效标识符
    TYPE_MISMATCH = "TYPE_MISMATCH"     # 类型不匹配
    UNDEFINED_REFERENCE = "UNDEFINED_REFERENCE"   # 未定义引用


class ErrorSeverity(Enum):
    """错误严重程度"""
    ERROR = "ERROR"       # 错误：必须修复
    WARNING = "WARNING"   # 警告：建议修复
    INFO = "INFO"         # 信息：可选修复


@dataclass
class ErrorInfo:
    """错误信息类"""
    error_type: ErrorType
    severity: ErrorSeverity
    message: str
    line: int
    column: int
    token_value: str = ""
    suggestions: List[str] = None
    context: str = ""
    
    def __post_init__(self):
        if self.suggestions is None:
            self.suggestions = []


@dataclass
class CorrectionSuggestion:
    """修复建议类"""
    original: str
    corrected: str
    confidence: float  # 0.0-1.0，修复置信度
    reason: str
    error_type: ErrorType


class SmartErrorCorrector:
    """智能纠错器"""
    
    def __init__(self):
        # SQL关键字集合（用于拼写检查）
        self.sql_keywords = {
            'SELECT', 'FROM', 'WHERE', 'CREATE', 'TABLE', 'INSERT', 'INTO',
            'UPDATE', 'DELETE', 'DROP', 'ALTER', 'INDEX', 'PRIMARY', 'KEY',
            'FOREIGN', 'REFERENCES', 'NOT', 'NULL', 'UNIQUE', 'DEFAULT',
            'CHECK', 'CONSTRAINT', 'DATABASE', 'SCHEMA', 'VIEW', 'TRIGGER',
            'PROCEDURE', 'FUNCTION', 'RETURN', 'BEGIN', 'END', 'IF', 'ELSE',
            'WHILE', 'FOR', 'LOOP', 'BREAK', 'CONTINUE', 'CASE', 'WHEN',
            'THEN', 'ORDER', 'BY', 'GROUP', 'HAVING', 'DISTINCT', 'ALL',
            'UNION', 'INTERSECT', 'EXCEPT', 'JOIN', 'INNER', 'LEFT', 'RIGHT',
            'FULL', 'OUTER', 'CROSS', 'ON', 'AS', 'IN', 'EXISTS', 'BETWEEN',
            'LIKE', 'IS', 'AND', 'OR', 'XOR', 'VALUES', 'INT', 'VARCHAR',
            'SET', 'ASC', 'DESC', 'USE', 'LIMIT', 'GRANT', 'REVOKE', 'TO',
            'WITH', 'OPTION', 'PRIVILEGES', 'PUBLIC', 'ROLE', 'USER',
            'LIST', 'SHOW', 'DATABASES', 'SCHEMAS', 'USERS', 'PASSWORD', 
            'IDENTIFIED', 'COUNT', 'SUM', 'AVG', 'MAX', 'MIN', 'STDDEV', 'VARIANCE'
        }
        
        # 常见拼写错误映射
        self.common_misspellings = {
            'SELCT': 'SELECT',
            'SLECT': 'SELECT',
            'SELET': 'SELECT',
            'FORM': 'FROM',
            'FRON': 'FROM',
            'WHRE': 'WHERE',
            'WHER': 'WHERE',
            'WERE': 'WHERE',  # 新增
            'CREAT': 'CREATE',
            'CRETE': 'CREATE',
            'TABEL': 'TABLE',
            'TABL': 'TABLE',
            'TABLLE': 'TABLE',
            'INSER': 'INSERT',
            'INSRT': 'INSERT',
            'UPDAT': 'UPDATE',
            'UPDAE': 'UPDATE',
            'DELET': 'DELETE',
            'DELEET': 'DELETE',
            'DATABSE': 'DATABASE',
            'DATABAS': 'DATABASE',
            'ODER': 'ORDER',
            'ORDR': 'ORDER',
            'GRUP': 'GROUP',
            'GRPUP': 'GROUP',
            'JION': 'JOIN',
            'JNOI': 'JOIN',
            'INEER': 'INNER',
            'INER': 'INNER',
            'LEFTT': 'LEFT',
            'RGHT': 'RIGHT',
            'RIGTH': 'RIGHT',
            'CUNT': 'COUNT',
            'COUT': 'COUNT',
            'CONUT': 'COUNT',
            'GRAN': 'GRANT'  # 新增
        }
        
        # 常见的数据库列名白名单，这些不应该被标记为拼写错误
        self.common_column_names = {
            'ID', 'NAME', 'AGE', 'EMAIL', 'PASSWORD', 'USERNAME', 'FIRSTNAME', 'LASTNAME',
            'PHONE', 'ADDRESS', 'CITY', 'STATE', 'COUNTRY', 'ZIPCODE', 'POSTCODE',
            'CREATED', 'UPDATED', 'MODIFIED', 'DELETED', 'STATUS', 'ACTIVE', 'ENABLED',
            'TYPE', 'CATEGORY', 'TITLE', 'DESCRIPTION', 'CONTENT', 'BODY', 'TEXT',
            'PRICE', 'COST', 'AMOUNT', 'QUANTITY', 'TOTAL', 'SUBTOTAL', 'TAX',
            'SCORE', 'RATING', 'RANK', 'LEVEL', 'GRADE', 'POINTS', 'VALUE',
            'DATE', 'TIME', 'DATETIME', 'TIMESTAMP', 'YEAR', 'MONTH', 'DAY',
            'HOUR', 'MINUTE', 'SECOND', 'START', 'END', 'BEGIN', 'FINISH',
            'MAJOR', 'MINOR', 'DEPARTMENT', 'COMPANY', 'ORGANIZATION', 'TEAM',
            'ROLE', 'POSITION', 'JOB', 'TITLE', 'SALARY', 'WAGE', 'INCOME',
            'HEIGHT', 'WEIGHT', 'SIZE', 'LENGTH', 'WIDTH', 'DEPTH', 'COLOR',
            'IMAGE', 'PHOTO', 'PICTURE', 'URL', 'LINK', 'PATH', 'FILE', 'FILENAME',
            'STUDENT_ID', 'USER_ID', 'CUSTOMER_ID', 'ORDER_ID', 'PRODUCT_ID'
        }
        
        # 语法模式和修复规则
        self.syntax_patterns = {
            'missing_select_list': {
                'pattern': r'SELECT\s+FROM\s+\w+',
                'suggestion': 'SELECT语句缺少列名列表',
                'fix': lambda match: match.group(0).replace('SELECT FROM', 'SELECT * FROM'),
                'priority': 1  # 高优先级
            },
            'missing_table_name': {
                'pattern': r'SELECT\s+[^;]+\s+FROM\s*;',
                'suggestion': 'FROM子句缺少表名',
                'fix': lambda match: match.group(0).replace('FROM ;', 'FROM <table_name>;'),
                'priority': 1  # 高优先级
            },
            'missing_from_clause': {
                # 仅当整条语句中完全不存在 FROM 时才判定为缺少FROM
                'pattern': r'^(?!.*\bFROM\b)\s*SELECT\s+\w+(?:\s+\w+)+\s*(?:;|$)',
                'suggestion': 'SELECT语句缺少FROM关键字',
                'fix': lambda match: self._fix_missing_from(match.group(0)),
                'priority': 1  # 高优先级
            },
            'incomplete_where_clause': {
                'pattern': r'WHERE\s*;',
                'suggestion': 'WHERE子句不完整，缺少条件表达式',
                'fix': lambda match: 'WHERE <condition>;',
                'priority': 1
            },
            'incomplete_and_condition': {
                'pattern': r'AND\s*;',
                'suggestion': 'AND后缺少条件表达式',
                'fix': lambda match: 'AND <condition>;',
                'priority': 1
            },
            'incomplete_or_condition': {
                'pattern': r'WHERE\s+OR\s',
                'suggestion': 'OR前缺少条件表达式',
                'fix': lambda match: 'WHERE <condition> OR ',
                'priority': 1
            },
            'missing_comma_in_create': {
                'pattern': r'CREATE\s+TABLE\s+\w+\s*\(.*?\w+\s+\w+\s+\w+\s+\w+.*?\)',
                'suggestion': 'CREATE TABLE列定义中缺少逗号分隔符',
                'fix': lambda match: match.group(0).replace(r'(\w+\s+\w+)\s+(\w+\s+\w+)', r'\1, \2'),
                'priority': 1
            },
            'missing_table_keyword': {
                'pattern': r'DROP\s+(\w+)\s*;',
                'suggestion': 'DROP语句缺少TABLE关键字',
                'fix': lambda match: f"DROP TABLE {match.group(1)};",
                'priority': 1
            },
            'incomplete_drop_table': {
                'pattern': r'DROP\s+TABLE\s*;',
                'suggestion': 'DROP TABLE语句缺少表名',
                'fix': lambda match: 'DROP TABLE <table_name>;',
                'priority': 1
            },
            'incomplete_set_clause': {
                'pattern': r'UPDATE\s+\w+\s+SET\s+WHERE',
                'suggestion': 'UPDATE语句SET子句不完整',
                'fix': lambda match: match.group(0).replace('SET WHERE', 'SET <column>=<value> WHERE'),
                'priority': 1
            },
            'missing_from_in_delete': {
                'pattern': r'DELETE\s+(\w+)\s+WHERE',
                'suggestion': 'DELETE语句缺少FROM关键字',
                'fix': lambda match: f"DELETE FROM {match.group(1)} WHERE",
                'priority': 1
            },
            'illegal_character': {
                'pattern': r'[@#$%^&*\[\]{}|\\]',
                'suggestion': '包含非法字符',
                'fix': lambda match: '<检查并移除非法字符>',
                'priority': 2
            },
            'wrong_operator': {
                'pattern': r'&&|\|\||==',
                'suggestion': '使用了错误的操作符',
                'fix': lambda match: {'&&': 'AND', '||': 'OR', '==': '='}.get(match.group(0), match.group(0)),
                'priority': 99  # 由词法层处理，避免与词法重复
            },
            'missing_quotes': {
                'pattern': r'=\s*([a-zA-Z][a-zA-Z0-9_]*)\s*(?:;|AND|OR|$)',
                'suggestion': '字符串值缺少引号',
                'fix': lambda match: f"= '{match.group(1)}'",
                'priority': 2
            },
            'trailing_comma': {
                'pattern': r',\s*(FROM|WHERE|ORDER|GROUP|HAVING|;)',
                'suggestion': '多余的逗号',
                'fix': lambda match: '删除多余的逗号',
                'priority': 99  # 由词法层处理，避免与词法重复
            },
            'double_semicolon': {
                'pattern': r';;+',
                'suggestion': '多余的分号',
                'fix': lambda match: ';',
                'priority': 2
            },
            'missing_semicolon': {
                'pattern': r'(?:SELECT|INSERT|UPDATE|DELETE|CREATE|DROP)\s+.*[^;]\s*$',
                'suggestion': '语句末尾缺少分号',
                'fix': lambda match: match.group(0) + ';',
                'priority': 2  # 中优先级
            },
            'missing_comma': {
                'pattern': r'SELECT\s+(\w+)\s+(\w+)\s+FROM',
                'suggestion': 'SELECT列表中可能缺少逗号',
                'fix': lambda match: f"SELECT {match.group(1)}, {match.group(2)} FROM",
                'priority': 2  # 中优先级
            },
            'empty_select_after_comma': {
                'pattern': r'SELECT\s+[^,]+,\s*FROM',
                'suggestion': 'SELECT列表中逗号后缺少列名',
                'fix': lambda match: match.group(0).replace(', FROM', ', <column_name> FROM'),
                'priority': 2  # 中优先级
            },
            'duplicate_keywords': {
                'pattern': r'\b(SELECT|CREATE|DROP|UPDATE|DELETE|WHERE|ORDER|GROUP)\s+\1\b',
                'suggestion': '重复的关键字',
                'fix': lambda match: match.group(1),
                'priority': 2
            }
        }
        
        # 错误收集器
        self.errors: List[ErrorInfo] = []
        self.suggestions: List[CorrectionSuggestion] = []
    
    def _fix_missing_from(self, stmt: str) -> str:
        """将类似 'SELECT col table' 修复为 'SELECT col FROM table;' 的安全修复。
        若无法可靠识别两段标识符，则原样返回。
        """
        try:
            text = stmt.strip().rstrip(';')
            # 捕获多个标识符，优先取前两个作为 列 与 表
            m = re.match(r'^SELECT\s+([A-Za-z_][A-Za-z0-9_]*)\s+([A-Za-z_][A-Za-z0-9_]*)(?:\s+.*)?$', text, re.IGNORECASE)
            if m:
                col = m.group(1)
                table = m.group(2)
                return f"SELECT {col} FROM {table};"
        except Exception:
            pass
        return stmt

    def clear_errors(self):
        """清空错误记录"""
        self.errors.clear()
        self.suggestions.clear()
    
    def add_error(self, error_info: ErrorInfo):
        """添加错误信息（带去重）"""
        # 检查是否已存在类似错误，避免重复
        for existing_error in self.errors:
            if (existing_error.line == error_info.line and 
                existing_error.column == error_info.column and
                existing_error.error_type == error_info.error_type and
                existing_error.message == error_info.message):
                return  # 跳过重复错误
        
        self.errors.append(error_info)
    
    def add_suggestion(self, suggestion: CorrectionSuggestion):
        """添加修复建议"""
        self.suggestions.append(suggestion)
    
    def check_spelling(self, word: str, line: int, column: int) -> Optional[ErrorInfo]:
        """检查单词拼写"""
        word_upper = word.upper()
        
        # 跳过常见的列名，避免误报
        if word_upper in self.common_column_names:
            return None
        
        # 跳过包含下划线的标识符（通常是用户自定义名称）
        if '_' in word:
            return None
        
        # 跳过包含数字的标识符（通常是用户自定义名称）
        if any(c.isdigit() for c in word):
            return None
        
        # 检查是否是已知的错误拼写
        if word_upper in self.common_misspellings:
            correct_word = self.common_misspellings[word_upper]
            error = ErrorInfo(
                error_type=ErrorType.SPELLING,
                severity=ErrorSeverity.WARNING,
                message=f"可能的拼写错误: '{word}' -> '{correct_word}'",
                line=line,
                column=column,
                token_value=word,
                suggestions=[correct_word]
            )
            return error
        
        # 使用模糊匹配查找相似的关键字（提高阈值，减少误报）
        if word_upper not in self.sql_keywords and len(word) > 2:
            close_matches = difflib.get_close_matches(
                word_upper, self.sql_keywords, n=3, cutoff=0.8  # 从0.6提高到0.8
            )
            if close_matches:
                # 额外检查：只有当匹配度很高时才报告拼写错误
                best_match = close_matches[0]
                similarity = difflib.SequenceMatcher(None, word_upper, best_match).ratio()
                if similarity > 0.85:  # 只有相似度很高时才认为是拼写错误
                    error = ErrorInfo(
                        error_type=ErrorType.SPELLING,
                        severity=ErrorSeverity.WARNING,
                        message=f"可能的拼写错误: '{word}'，您是否想输入: {', '.join(close_matches)}",
                        line=line,
                        column=column,
                        token_value=word,
                        suggestions=close_matches
                    )
                    return error
        
        return None
    
    def _is_char_in_string(self, text: str, pos: int) -> bool:
        """检查指定位置的字符是否在字符串字面量内部"""
        # 查找字符前面最近的引号
        before_pos = pos - 1
        quote_count_single = 0
        quote_count_double = 0
        
        i = 0
        while i <= before_pos and i < len(text):
            if text[i] == "'" and (i == 0 or text[i-1] != '\\'):
                quote_count_single += 1
            elif text[i] == '"' and (i == 0 or text[i-1] != '\\'):
                quote_count_double += 1
            i += 1
        
        # 如果单引号或双引号数量为奇数，说明在字符串内部
        return (quote_count_single % 2 == 1) or (quote_count_double % 2 == 1)
    
    def analyze_lexical_errors(self, text: str, tokens: List[Any]) -> List[ErrorInfo]:
        """分析词法错误"""
        errors = []
        
        # 检查非法字符（排除SQL中合法的符号，包括*）
        # 但需要智能处理字符串内的通配符
        illegal_chars = re.findall(r'[@#$^&\[\]{}|\\]', text)  # 移除了%，因为它在LIKE中是合法的
        if illegal_chars:
            for char in set(illegal_chars):  # 去重
                if char in text:
                    pos = text.find(char)
                    # 检查字符是否在字符串内部
                    if not self._is_char_in_string(text, pos):
                        error = ErrorInfo(
                            error_type=ErrorType.LEXICAL,
                            severity=ErrorSeverity.ERROR,
                            message=f"包含非法字符 '{char}'",
                            line=1,
                            column=pos + 1,
                            token_value=char,
                            suggestions=[
                                f"移除非法字符 '{char}'",
                                "检查是否为输入错误"
                            ]
                        )
                        errors.append(error)
        
        # 检查错误的操作符
        wrong_operators = re.findall(r'&&|\|\||==', text)
        if wrong_operators:
            for op in set(wrong_operators):
                if op in text:
                    pos = text.find(op)
                    correct_op = {'&&': 'AND', '||': 'OR', '==': '='}.get(op, op)
                    error = ErrorInfo(
                        error_type=ErrorType.LEXICAL,
                        severity=ErrorSeverity.ERROR,
                        message=f"错误的操作符 '{op}'",
                        line=1,
                        column=pos + 1,
                        token_value=op,
                        suggestions=[
                            f"将 '{op}' 替换为 '{correct_op}'",
                            f"使用SQL标准操作符 '{correct_op}'"
                        ]
                    )
                    errors.append(error)
        
        # 检查缺少引号的字符串
        missing_quotes = re.findall(r'=\s*([a-zA-Z][a-zA-Z0-9_]*)\s*(?:;|AND|OR|$)', text)
        if missing_quotes:
            for word in set(missing_quotes):
                if word.upper() not in self.sql_keywords:
                    pos = text.find(f'= {word}')
                    if pos == -1:
                        pos = text.find(f'={word}')
                    if pos != -1:
                        error = ErrorInfo(
                            error_type=ErrorType.LEXICAL,
                            severity=ErrorSeverity.WARNING,
                            message=f"字符串值 '{word}' 缺少引号",
                            line=1,
                            column=pos + text[pos:].find(word) + 1,
                            token_value=word,
                            suggestions=[
                                f"= '{word}'",
                                f"= \"{word}\""
                            ]
                        )
                        errors.append(error)
        
        # 检查多余的逗号
        trailing_commas = re.findall(r',\s*(FROM|WHERE|ORDER|GROUP|HAVING|;)', text, re.IGNORECASE)
        if trailing_commas:
            for match in trailing_commas:
                pos = text.find(f', {match}')
                if pos == -1:
                    pos = text.find(f',{match}')
                if pos != -1:
                    error = ErrorInfo(
                        error_type=ErrorType.LEXICAL,
                        severity=ErrorSeverity.WARNING,
                        message="多余的逗号",
                        line=1,
                        column=pos + 1,
                        suggestions=[
                            "删除多余的逗号"
                        ]
                    )
                    errors.append(error)
        
        # 检查多余的分号
        double_semicolons = re.findall(r';;+', text)
        if double_semicolons:
            # 找到第二个分号的位置
            first_semicolon = text.find(';')
            second_semicolon = text.find(';', first_semicolon + 1)
            if second_semicolon != -1:
                error = ErrorInfo(
                    error_type=ErrorType.LEXICAL,
                    severity=ErrorSeverity.WARNING,
                    message="多余的分号",
                    line=1,
                    column=second_semicolon + 1,
                    suggestions=[
                        "删除多余的分号",
                        "仅保留一个分号 ';'"
                    ]
                )
                errors.append(error)
        
        # 检查未闭合的字符串
        lines = text.split('\n')
        for line_num, line in enumerate(lines, 1):
            # 检查单引号字符串
            single_quote_count = line.count("'") - line.count("\\'")
            if single_quote_count % 2 != 0:
                error = ErrorInfo(
                    error_type=ErrorType.LEXICAL,
                    severity=ErrorSeverity.ERROR,
                    message="未闭合的单引号字符串",
                    line=line_num,
                    column=line.rfind("'") + 1,
                    suggestions=["添加闭合单引号 '"]
                )
                errors.append(error)
            
            # 检查双引号字符串
            double_quote_count = line.count('"') - line.count('\\"')
            if double_quote_count % 2 != 0:
                error = ErrorInfo(
                    error_type=ErrorType.LEXICAL,
                    severity=ErrorSeverity.ERROR,
                    message="未闭合的双引号字符串",
                    line=line_num,
                    column=line.rfind('"') + 1,
                    suggestions=['添加闭合双引号 "']
                )
                errors.append(error)
        
        # 检查关键字拼写
        for token in tokens:
            # 使用 hasattr 检查 token 是否有相应属性，避免直接依赖 TokenType
            if hasattr(token, 'type') and hasattr(token, 'value') and hasattr(token, 'line') and hasattr(token, 'column'):
                # 检查是否是标识符类型（通过名称判断）
                if hasattr(token.type, 'name') and token.type.name == 'IDENTIFIER':
                    spelling_error = self.check_spelling(token.value, token.line, token.column)
                    if spelling_error:
                        errors.append(spelling_error)
        
        return errors
    
    def analyze_syntax_errors(self, text: str, parse_errors: List[str]) -> List[ErrorInfo]:
        """分析语法错误"""
        errors = []
        
        # 首先进行智能模式检测，优先处理常见语法错误
        pattern_errors = self._detect_syntax_patterns(text)
        errors.extend(pattern_errors)
        
        # 然后分析解析器返回的错误（如果模式检测没有覆盖到）
        if not pattern_errors:  # 只有在没有找到明确模式时才分析解析器错误
            for parse_error in parse_errors:
                # 跳过语义错误，避免误分类
                if parse_error.startswith('语义错误') or '不存在' in parse_error or '已存在' in parse_error:
                    continue
                    
                # 尝试从错误消息中提取位置信息
                line_match = re.search(r'第(\d+)行', parse_error)
                column_match = re.search(r'第(\d+)列', parse_error)
                
                line_num = int(line_match.group(1)) if line_match else 1
                column_num = int(column_match.group(1)) if column_match else 1
                
                # 根据错误类型生成建议（考虑原始SQL文本，避免误判缺少FROM）
                suggestions = self._generate_syntax_suggestions(parse_error, text)
                
                error = ErrorInfo(
                    error_type=ErrorType.SYNTAX,
                    severity=ErrorSeverity.ERROR,
                    message=parse_error,
                    line=line_num,
                    column=column_num,
                    suggestions=suggestions,
                    context=text
                )
                # 去重：避免对同一位置、同一类型（如操作符/逗号）重复报告
                is_duplicate = False
                for e in errors:
                    if (e.line == error.line and e.column == error.column and e.message == error.message):
                        is_duplicate = True
                        break
                if not is_duplicate:
                    errors.append(error)
        
        return errors
    
    def _detect_syntax_patterns(self, text: str) -> List[ErrorInfo]:
        """检测语法模式错误"""
        errors = []
        text_clean = text.strip()
        
        # 专门的错误检测逻辑，按优先级处理
        
        # 1. 检测缺少选择列表 (SELECT FROM ...)
        select_from_match = re.match(r'SELECT\s+FROM\s+(\w+)', text_clean, re.IGNORECASE)
        if select_from_match:
            table_name = select_from_match.group(1)
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="SELECT语句缺少列名列表",
                line=1,
                column=8,  # FROM位置
                context=text_clean,
                suggestions=[
                    f"SELECT * FROM {table_name}",
                    f"SELECT <column_name> FROM {table_name}"
                ]
            )
            errors.append(error)
            return errors  # 返回最重要的错误
        
        # 2. 检测缺少表名 (SELECT name FROM;)
        missing_table_match = re.match(r'SELECT\s+([^;]+)\s+FROM\s*;', text_clean, re.IGNORECASE)
        if missing_table_match:
            columns = missing_table_match.group(1).strip()
            from_pos = text_clean.rfind('FROM')
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="FROM子句缺少表名",
                line=1,
                column=from_pos + 5,  # FROM后的位置
                context=text_clean,
                suggestions=[
                    f"SELECT {columns} FROM <table_name>;",
                    f"SELECT {columns} FROM <table_name2>;"
                ]
            )
            errors.append(error)
            return errors  # 返回最重要的错误
        
        # 3. 检测缺少FROM关键字 (SELECT name Students;) - 仅当确实没有FROM时
        missing_from_match = re.match(r'SELECT\s+(\w+)\s+(\w+)\s*;?', text_clean, re.IGNORECASE)
        if missing_from_match:
            # 严格验证：必须确认没有FROM关键字
            if not re.search(r'\bFROM\b', text_clean, re.IGNORECASE):
                column_name = missing_from_match.group(1)
                table_name = missing_from_match.group(2)
                table_pos = text_clean.find(table_name)
                error = ErrorInfo(
                    error_type=ErrorType.MISSING_TOKEN,
                    severity=ErrorSeverity.ERROR,
                    message="SELECT语句缺少FROM关键字",
                    line=1,
                    column=table_pos,  # 表名位置
                    context=text_clean,
                    suggestions=[
                        f"SELECT {column_name} FROM {table_name};",
                        f"SELECT * FROM {table_name};"
                    ]
                )
                errors.append(error)
                return errors  # 返回最重要的错误
        
        # 4. 检测WHERE子句不完整
        where_incomplete_match = re.search(r'WHERE\s*;', text_clean, re.IGNORECASE)
        if where_incomplete_match:
            where_pos = where_incomplete_match.start()
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="WHERE子句不完整，缺少条件表达式",
                line=1,
                column=where_pos + 6,  # WHERE后的位置
                context=text_clean,
                suggestions=[
                    text_clean.replace('WHERE;', 'WHERE <condition>;'),
                    text_clean.replace('WHERE;', 'WHERE <column> = <value>;')
                ]
            )
            errors.append(error)
            return errors
        
        # 5. 检测AND后缺少条件
        and_incomplete_match = re.search(r'AND\s*;', text_clean, re.IGNORECASE)
        if and_incomplete_match:
            and_pos = and_incomplete_match.start()
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="AND后缺少条件表达式",
                line=1,
                column=and_pos + 4,  # AND后的位置
                context=text_clean,
                suggestions=[
                    text_clean.replace('AND;', 'AND <condition>;'),
                    text_clean.replace('AND;', 'AND <column> = <value>;')
                ]
            )
            errors.append(error)
            return errors
        
        # 6. 检测OR前缺少条件
        or_incomplete_match = re.search(r'WHERE\s+OR\s', text_clean, re.IGNORECASE)
        if or_incomplete_match:
            or_pos = or_incomplete_match.start() + 6  # WHERE后的位置
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="OR前缺少条件表达式",
                line=1,
                column=or_pos,
                context=text_clean,
                suggestions=[
                    text_clean.replace('WHERE OR', 'WHERE <condition> OR'),
                    text_clean.replace('WHERE OR', 'WHERE <column> = <value> OR')
                ]
            )
            errors.append(error)
            return errors
        
        # 7. 检测CREATE TABLE中缺少逗号
        create_table_match = re.search(r'CREATE\s+TABLE\s+\w+\s*\(([^)]+)\)', text_clean, re.IGNORECASE)
        if create_table_match:
            columns_def = create_table_match.group(1)
            # 检查是否有连续的标识符没有逗号分隔
            if re.search(r'\w+\s+\w+\s+\w+\s+\w+', columns_def) and ',' not in columns_def:
                create_pos = create_table_match.start()
                error = ErrorInfo(
                    error_type=ErrorType.MISSING_TOKEN,
                    severity=ErrorSeverity.ERROR,
                    message="CREATE TABLE列定义中缺少逗号分隔符",
                    line=1,
                    column=create_pos,
                    context=text_clean,
                    suggestions=[
                        re.sub(r'(\w+\s+\w+)\s+(\w+\s+\w+)', r'\1, \2', text_clean),
                        "检查列定义之间是否缺少逗号"
                    ]
                )
                errors.append(error)
                return errors
        
        # 8. 检测DROP语句缺少TABLE关键字
        drop_without_table = re.match(r'DROP\s+(\w+)\s*;', text_clean, re.IGNORECASE)
        if drop_without_table and drop_without_table.group(1).upper() not in ['TABLE', 'DATABASE', 'USER', 'INDEX']:
            table_name = drop_without_table.group(1)
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="DROP语句缺少TABLE关键字",
                line=1,
                column=5,  # DROP后的位置
                context=text_clean,
                suggestions=[
                    f"DROP TABLE {table_name};",
                    "确认要删除的对象类型"
                ]
            )
            errors.append(error)
            return errors
        
        # 9. 检测DROP TABLE后缺少表名
        drop_table_incomplete = re.match(r'DROP\s+TABLE\s*;', text_clean, re.IGNORECASE)
        if drop_table_incomplete:
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="DROP TABLE语句缺少表名",
                line=1,
                column=11,  # "DROP TABLE"后的位置
                context=text_clean,
                suggestions=[
                    "DROP TABLE <table_name>;",
                    "指定要删除的表名"
                ]
            )
            errors.append(error)
            return errors
        
        # 10. 检测UPDATE SET子句不完整
        update_set_incomplete = re.search(r'UPDATE\s+\w+\s+SET\s+WHERE', text_clean, re.IGNORECASE)
        if update_set_incomplete:
            set_pos = text_clean.find('SET', update_set_incomplete.start())
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="UPDATE语句SET子句不完整",
                line=1,
                column=set_pos + 4,  # SET后的位置
                context=text_clean,
                suggestions=[
                    text_clean.replace('SET WHERE', 'SET <column>=<value> WHERE'),
                    "在SET和WHERE之间添加列赋值表达式"
                ]
            )
            errors.append(error)
            return errors
        
        # 11. 检测DELETE语句缺少FROM
        delete_without_from = re.search(r'DELETE\s+(\w+)\s+WHERE', text_clean, re.IGNORECASE)
        if delete_without_from:
            table_name = delete_without_from.group(1)
            delete_pos = delete_without_from.start()
            error = ErrorInfo(
                error_type=ErrorType.MISSING_TOKEN,
                severity=ErrorSeverity.ERROR,
                message="DELETE语句缺少FROM关键字",
                line=1,
                column=delete_pos + 7,  # DELETE后的位置
                context=text_clean,
                suggestions=[
                    f"DELETE FROM {table_name} WHERE",
                    "在DELETE和表名之间添加FROM关键字"
                ]
            )
            errors.append(error)
            return errors
        
        # 12. 使用原有的正则表达式模式检查其他错误
        for pattern_name, pattern_info in self.syntax_patterns.items():
            if pattern_info.get('priority', 3) <= 2:  # 只处理高优先级和中优先级
                matches = re.finditer(pattern_info['pattern'], text_clean, re.IGNORECASE)
                for match in matches:
                    # 计算行号和列号
                    line_num = text_clean[:match.start()].count('\n') + 1
                    line_start = text_clean.rfind('\n', 0, match.start()) + 1
                    column_num = match.start() - line_start + 1
                    
                    # 跳过已经处理过的错误
                    if any(existing_error.line == line_num and 
                          abs(existing_error.column - column_num) < 5 
                          for existing_error in errors):
                        continue
                    
                    try:
                        fixed_text = pattern_info['fix'](match)
                    except:
                        fixed_text = "<修复建议>"
                    
                    error = ErrorInfo(
                        error_type=ErrorType.SYNTAX,
                        severity=ErrorSeverity.ERROR,
                        message=pattern_info['suggestion'],
                        line=line_num,
                        column=column_num,
                        context=match.group(0),
                        suggestions=[fixed_text]
                    )
                    errors.append(error)
        
        return errors
    
    def analyze_semantic_errors(self, semantic_errors: List[str], 
                              predefined_tables: Dict[str, List[str]], 
                              predefined_databases: Set[str]) -> List[ErrorInfo]:
        """分析语义错误"""
        errors = []
        
        for semantic_error in semantic_errors:
            # 提取位置信息
            line_match = re.search(r'第(\d+)行', semantic_error)
            column_match = re.search(r'第(\d+)列', semantic_error)
            
            line_num = int(line_match.group(1)) if line_match else 1
            column_num = int(column_match.group(1)) if column_match else 1
            
            # 分析错误类型并生成建议
            suggestions = []
            error_type = ErrorType.SEMANTIC
            
            if "不存在" in semantic_error:
                if "表" in semantic_error:
                    # 表不存在错误
                    table_match = re.search(r"表 '(\w+)' 不存在", semantic_error)
                    if table_match:
                        table_name = table_match.group(1)
                        suggestions = self._suggest_similar_tables(table_name, predefined_tables)
                        error_type = ErrorType.UNDEFINED_REFERENCE
                
                elif "列" in semantic_error:
                    # 列不存在错误
                    column_match = re.search(r"列 '(\w+)' 不存在于表 '(\w+)' 中", semantic_error)
                    if column_match:
                        column_name = column_match.group(1)
                        table_name = column_match.group(2)
                        if table_name in predefined_tables:
                            suggestions = self._suggest_similar_columns(
                                column_name, predefined_tables[table_name]
                            )
                        error_type = ErrorType.UNDEFINED_REFERENCE
                
                elif "数据库" in semantic_error:
                    # 数据库不存在错误
                    db_match = re.search(r"数据库 '(\w+)' 不存在", semantic_error)
                    if db_match:
                        db_name = db_match.group(1)
                        suggestions = self._suggest_similar_databases(db_name, predefined_databases)
                        error_type = ErrorType.UNDEFINED_REFERENCE
            
            elif "已存在" in semantic_error:
                suggestions = ["使用不同的名称", "添加IF NOT EXISTS子句"]
            
            elif "重复定义" in semantic_error:
                suggestions = ["使用不同的名称", "检查是否重复声明"]
            
            error = ErrorInfo(
                error_type=error_type,
                severity=ErrorSeverity.ERROR,
                message=semantic_error,
                line=line_num,
                column=column_num,
                suggestions=suggestions
            )
            errors.append(error)
        
        return errors
    
    def _generate_syntax_suggestions(self, error_message: str, text: str = "") -> List[str]:
        """根据语法错误消息生成修复建议"""
        suggestions = []
        
        # 针对三种核心语法错误的专门处理
        
        # 1. SELECT FROM语句缺少列名的特定处理
        if "SelList" in error_message and "FROM" in error_message:
            suggestions.extend([
                "SELECT语句缺少列名列表",
                "修复建议: SELECT * FROM <table_name>; (查询所有列)",
                "修复建议: SELECT column_name FROM <table_name>; (查询指定列)"
            ])
            return suggestions
        
        # 2. FROM后缺少表名的处理
        if "TblAlias" in error_message and ";" in error_message:
            suggestions.extend([
                "FROM子句缺少表名",
                "修复建议: SELECT <columns> FROM <table_name>;",
                "示例: SELECT <column> FROM <table>;"
            ])
            return suggestions
        
        # 3. 缺少FROM关键字的处理
        if "QualifiedIDRest" in error_message and "ID_TOKEN" in error_message:
            # 仅当SQL文本中确实不存在FROM时，才给出缺少FROM的建议
            if text and re.search(r"\bFROM\b", text, re.IGNORECASE):
                # 存在FROM，避免误导性建议
                suggestions.extend([
                    "语法错误: 在标识符附近",
                    "检查该位置是否缺少逗号或操作符"
                ])
                return suggestions
            suggestions.extend([
                "SELECT语句缺少FROM关键字",
                "修复建议: SELECT <columns> FROM <table_name>;",
                "正确语法: SELECT <column> FROM <table>;"
            ])
            return suggestions
        
        # 针对SELECT FROM语句缺少列名的兼容处理
        if "期望" in error_message and ("SelectItem" in error_message or "SelList" in error_message):
            suggestions.extend([
                "SELECT后面缺少列名，请添加要查询的列名",
                "修复方案1: SELECT * FROM <table_name>; (查询所有列)",
                "修复方案2: SELECT column1, column2 FROM <table_name>; (查询指定列)",
                "修复方案3: SELECT COUNT(*) FROM <table_name>; (统计记录数)"
            ])
            return suggestions
        
        # 针对LIST/SHOW语句的USERS支持检查
        if "USERS" in error_message and ("期望" in error_message or "无效" in error_message):
            suggestions.extend([
                "LIST USERS 和 SHOW USERS 语句现在已支持",
                "请确认语法: LIST USERS; 或 SHOW USERS;",
                "如果仍然失败，请检查是否使用了正确的关键字"
            ])
            return suggestions
        
        # 通用错误处理
        if "期望" in error_message and "得到" in error_message:
            expected_match = re.search(r"期望.*?'([^']+)'", error_message)
            got_match = re.search(r"得到.*?'([^']+)'", error_message)
            
            if expected_match and got_match:
                expected = expected_match.group(1)
                got = got_match.group(1)
                suggestions.append(f"将 '{got}' 替换为 '{expected}'")
                
                # 特殊情况处理
                if expected == "FROM" and got in ["DATABASES", "USERS", "SCHEMAS"]:
                    suggestions.extend([
                        "这可能是LIST/SHOW语句的语法问题",
                        f"正确语法: LIST {got}; 或 SHOW {got};"
                    ])
        
        if "缺少" in error_message:
            missing_match = re.search(r"缺少.*?'([^']+)'", error_message)
            if missing_match:
                missing = missing_match.group(1)
                suggestions.append(f"添加缺少的 '{missing}'")
        
        if "意外" in error_message:
            suggestions.append("检查语句结构是否正确")
            suggestions.append("确认关键字的使用位置")
        
        # 针对常见错误的特定建议
        if "FROM" in error_message:
            suggestions.append("SELECT语句必须包含FROM子句")
            suggestions.append("检查表名是否正确")
        
        if "WHERE" in error_message:
            suggestions.append("WHERE子句需要包含条件表达式")
            suggestions.append("检查比较运算符的使用")
        
        if "分号" in error_message or ";" in error_message:
            suggestions.append("在语句末尾添加分号 ';'")
        
        if "逗号" in error_message or "," in error_message:
            suggestions.append("检查列表项之间是否需要逗号分隔")
        
        return suggestions if suggestions else ["检查SQL语法结构"]
    
    def _suggest_similar_tables(self, table_name: str, predefined_tables: Dict[str, List[str]]) -> List[str]:
        """建议相似的表名"""
        table_names = list(predefined_tables.keys())
        close_matches = difflib.get_close_matches(table_name, table_names, n=2, cutoff=0.6)
        
        suggestions = []
        if close_matches:
            suggestions.extend([f"使用表名: {name}" for name in close_matches])
            suggestions.append(f"检查是否拼写错误: '{table_name}'")
        else:
            suggestions.append(f"表 '{table_name}' 不存在")
            if predefined_tables:
                available_tables = ', '.join(list(predefined_tables.keys())[:3])
                suggestions.append(f"可用表名: {available_tables}")
            suggestions.append("确认表是否已创建")
        
        return suggestions
    
    def _suggest_similar_columns(self, column_name: str, table_columns: List[str]) -> List[str]:
        """建议相似的列名"""
        close_matches = difflib.get_close_matches(column_name, table_columns, n=2, cutoff=0.6)
        
        suggestions = []
        if close_matches:
            suggestions.extend([f"使用列名: {name}" for name in close_matches])
            suggestions.append(f"检查是否拼写错误: '{column_name}'")
        else:
            suggestions.append(f"列 '{column_name}' 不存在")
            if table_columns:
                available_columns = ', '.join(table_columns[:4])
                suggestions.append(f"可用列名: {available_columns}")
        
        return suggestions
    
    def _suggest_similar_databases(self, db_name: str, predefined_databases: Set[str]) -> List[str]:
        """建议相似的数据库名"""
        db_names = list(predefined_databases)
        close_matches = difflib.get_close_matches(db_name, db_names, n=2, cutoff=0.6)
        
        suggestions = []
        if close_matches:
            suggestions.extend([f"使用数据库: {name}" for name in close_matches])
            suggestions.append(f"检查是否拼写错误: '{db_name}'")
        else:
            suggestions.append(f"数据库 '{db_name}' 不存在")
            if predefined_databases:
                available_dbs = ', '.join(list(predefined_databases)[:3])
                suggestions.append(f"可用数据库: {available_dbs}")
            suggestions.append("确认数据库是否已创建")
        
        return suggestions
    
    def generate_correction_suggestions(self, text: str, errors: List[ErrorInfo]) -> List[CorrectionSuggestion]:
        """生成修复建议"""
        corrections = []
        
        for error in errors:
            if error.suggestions:
                for suggestion in error.suggestions:
                    # 计算修复的置信度
                    confidence = self._calculate_confidence(error, suggestion)
                    
                    # 为某些错误类型动态生成更具体的建议
                    original_text = error.context or text.strip()
                    corrected_text = self._generate_dynamic_correction(text, error, suggestion)
                    
                    correction = CorrectionSuggestion(
                        original=original_text,
                        corrected=corrected_text,
                        confidence=confidence,
                        reason=error.message,
                        error_type=error.error_type
                    )
                    corrections.append(correction)
        
        # 按置信度排序
        corrections.sort(key=lambda x: x.confidence, reverse=True)
        return corrections
    
    def _generate_dynamic_correction(self, original_text: str, error: ErrorInfo, suggestion: str) -> str:
        """基于原始文本和建议生成动态修复"""
        original_clean = original_text.strip()
        
        # 如果建议已经是完整的SQL语句，直接返回
        if suggestion.startswith('SELECT') and ';' in suggestion:
            return suggestion
        
        # 对于缺少选择列表的情况 (SELECT FROM table)
        if error.error_type == ErrorType.MISSING_TOKEN and "列名列表" in error.message:
            match = re.match(r'SELECT\s+FROM\s+(\w+)', original_clean, re.IGNORECASE)
            if match:
                table_name = match.group(1)
                if "SELECT *" in suggestion:
                    return f"SELECT * FROM {table_name};"
                elif "SELECT <column_name>" in suggestion:
                    return f"SELECT <column_name> FROM {table_name};"
                elif "SELECT <column1>, <column2>" in suggestion:
                    return f"SELECT <column1>, <column2> FROM {table_name};"
        
        # 对于缺少表名的情况 (SELECT columns FROM;)
        elif error.error_type == ErrorType.MISSING_TOKEN and "表名" in error.message:
            match = re.match(r'SELECT\s+([^;]+)\s+FROM\s*;', original_clean, re.IGNORECASE)
            if match:
                columns = match.group(1).strip()
                if "<table_name>" in suggestion:
                    return f"SELECT {columns} FROM <table_name>;"
                else:
                    return suggestion
        
        # 对于缺少FROM关键字的情况 (SELECT column table)
        elif error.error_type == ErrorType.MISSING_TOKEN and "FROM关键字" in error.message:
            match = re.match(r'SELECT\s+(\w+)\s+(\w+)\s*;?', original_clean, re.IGNORECASE)
            if match:
                column_name = match.group(1)
                table_name = match.group(2)
                return f"SELECT {column_name} FROM {table_name};"
        
        # 默认返回原始建议
        return suggestion
    
    def _calculate_confidence(self, error: ErrorInfo, suggestion: str) -> float:
        """计算修复建议的置信度"""
        confidence = 0.5  # 基础置信度
        
        # 根据错误类型调整置信度
        if error.error_type == ErrorType.SPELLING:
            if error.token_value.upper() in self.common_misspellings:
                confidence = 0.9  # 已知拼写错误，高置信度
            else:
                confidence = 0.7  # 模糊匹配，中等置信度
        
        elif error.error_type == ErrorType.MISSING_TOKEN:
            confidence = 0.8  # 缺少符号通常容易确定
        
        elif error.error_type == ErrorType.UNEXPECTED_TOKEN:
            confidence = 0.6  # 意外符号需要更多上下文
        
        elif error.error_type == ErrorType.UNDEFINED_REFERENCE:
            if "使用" in suggestion:
                confidence = 0.8  # 相似名称匹配
            else:
                confidence = 0.5  # 一般性建议
        
        # 根据建议的具体性调整置信度
        if "检查" in suggestion or "确认" in suggestion:
            confidence *= 0.7  # 一般性建议降低置信度
        
        if "添加" in suggestion or "替换" in suggestion:
            confidence *= 1.1  # 具体操作建议提高置信度
        
        return min(confidence, 1.0)  # 确保不超过1.0
    
    def format_error_report(self) -> str:
        """格式化错误报告"""
        if not self.errors:
            return "✅ 未发现错误"
        
        report = "\n🔍 智能纠错报告\n" + "="*50 + "\n"
        
        # 按严重程度分组，只关注最重要的错误
        error_groups = {
            ErrorSeverity.ERROR: [],
            ErrorSeverity.WARNING: [],
            ErrorSeverity.INFO: []
        }
        
        for error in self.errors:
            error_groups[error.severity].append(error)
        
        # 优先显示错误，并限制数量避免信息过载
        for severity in [ErrorSeverity.ERROR, ErrorSeverity.WARNING, ErrorSeverity.INFO]:
            if error_groups[severity]:
                severity_icon = "❌" if severity == ErrorSeverity.ERROR else "⚠️" if severity == ErrorSeverity.WARNING else "ℹ️"
                
                # 对于错误，只显示最重要的1-2个
                errors_to_show = error_groups[severity]
                if severity == ErrorSeverity.ERROR:
                    errors_to_show = errors_to_show[:2]  # 最多显示2个错误
                elif severity == ErrorSeverity.WARNING:
                    errors_to_show = errors_to_show[:1]  # 最多显示1个警告
                
                report += f"\n{severity_icon} {severity.value}:\n"
                
                for error in errors_to_show:
                    # 简化错误消息，避免技术细节
                    simplified_message = self._simplify_error_message(error.message)
                    report += f"  第{error.line}行第{error.column}列: {simplified_message}\n"
                    
                    if error.suggestions:
                        report += "  建议修复:\n"
                        # 只显示最实用的建议
                        useful_suggestions = [s for s in error.suggestions[:2] if "修复建议" in s or "SELECT" in s or "FROM" in s]
                        if not useful_suggestions:
                            useful_suggestions = error.suggestions[:2]
                        
                        for i, suggestion in enumerate(useful_suggestions, 1):
                            report += f"    {i}. {suggestion}\n"
                    report += "\n"
        
        return report
    
    def _simplify_error_message(self, message: str, context: str = "") -> str:
        """简化错误消息，使其更用户友好"""
        # 移除技术术语，使用更直观的描述
        simplifications = {
            "非终结符 'SelList' 无法处理输入符号 'FROM'": "SELECT语句缺少列名列表",
            "非终结符 'TblAlias' 无法处理输入符号 ';'": "FROM子句缺少表名",
            # 对于 'QualifiedIDRest' -> 缺少FROM 的映射，加入上下文保护
            # 我们在下面按条件应用，而不是固定替换
            "理由: 非终结符": "语法错误:",
            "❌ ERROR:": "语法错误"
        }
        
        simplified = message
        for technical, simple in simplifications.items():
            simplified = simplified.replace(technical, simple)
        
        # 有条件地将 'QualifiedIDRest' 简化为“缺少FROM”，仅当上下文确实不包含FROM
        if "QualifiedIDRest" in message and "ID_TOKEN" in message:
            if not (context and re.search(r"\bFROM\b", context, re.IGNORECASE)):
                simplified = simplified.replace(
                    "非终结符 'QualifiedIDRest' 无法处理输入符号 'ID_TOKEN'",
                    "SELECT语句缺少FROM关键字"
                )
            else:
                simplified = simplified.replace(
                    "非终结符 'QualifiedIDRest' 无法处理输入符号 'ID_TOKEN'",
                    "语法错误: 在标识符附近"
                )
        
        return simplified
    
    def format_correction_suggestions(self) -> str:
        """格式化修复建议"""
        if not self.suggestions:
            return ""
        
        report = "\n💡 智能修复建议\n" + "="*50 + "\n"
        
        # 按置信度分组显示，但简化输出
        high_confidence = [s for s in self.suggestions if s.confidence >= 0.7]
        low_confidence = [s for s in self.suggestions if s.confidence < 0.7]
        
        if high_confidence:
            report += "\n🎯 推荐修复:\n"
            for suggestion in high_confidence[:3]:  # 最多显示3个高置信度建议
                # 简化建议内容，突出实际的修复代码
                if suggestion.corrected and suggestion.original:
                    report += f"  '{suggestion.original}' → '{suggestion.corrected}' "
                    report += f"(置信度: {suggestion.confidence:.1%})\n"
                else:
                    # 如果没有具体的原始/修复文本，显示原因作为建议
                    simplified_reason = self._simplify_error_message(suggestion.reason)
                    report += f"  {simplified_reason}\n"
                report += "\n"
        
        if low_confidence and len(high_confidence) == 0:
            report += "\n💭 低置信度修复 (仅供参考):\n"
            for suggestion in low_confidence[:2]:  # 最多显示2个
                if suggestion.corrected and suggestion.original:
                    report += f"  '{suggestion.original}' → '{suggestion.corrected}' "
                    report += f"(置信度: {suggestion.confidence:.1%})\n"
                else:
                    simplified_reason = self._simplify_error_message(suggestion.reason)
                    report += f"  {simplified_reason}\n"
                report += "\n"
        
        return report
    
    def get_error_summary(self) -> Dict[str, int]:
        """获取错误统计摘要"""
        summary = {
            'total_errors': len(self.errors),
            'error_count': len([e for e in self.errors if e.severity == ErrorSeverity.ERROR]),
            'warning_count': len([e for e in self.errors if e.severity == ErrorSeverity.WARNING]),
            'info_count': len([e for e in self.errors if e.severity == ErrorSeverity.INFO]),
            'suggestions_count': len(self.suggestions)
        }
        return summary


def main():
    """测试主函数"""
    corrector = SmartErrorCorrector()
    
    # 测试用例
    test_cases = [
        "SELCT name FORM Students;",  # 拼写错误
        "SELECT name FROM Students",  # 缺少分号
        "SELECT FROM Students;",      # 缺少列名
        "SELECT name FROM UnknownTable;",  # 表不存在
        "SELECT unknown_col FROM Students;",  # 列不存在
        "SELECT name age FROM Students;",  # 缺少逗号
        "SELECT name FROM Students WHERE age > 'abc';",  # 类型错误
    ]
    
    print("智能纠错系统测试\n" + "="*50)
    
    for i, test_sql in enumerate(test_cases, 1):
        print(f"\n测试用例 {i}: {test_sql}")
        print("-" * 40)
        
        corrector.clear_errors()
        
        # 模拟词法分析错误检查（避免循环导入）
        try:
            # 创建模拟的 token 对象来测试
            class MockTokenType:
                def __init__(self, name):
                    self.name = name
            
            class MockToken:
                def __init__(self, token_type, value, line, column):
                    self.type = token_type
                    self.value = value
                    self.line = line
                    self.column = column
            
            # 简单的词法分析模拟
            mock_tokens = []
            words = test_sql.replace(';', ' ; ').split()
            for i, word in enumerate(words):
                if word in ['SELCT', 'FORM', 'WHER']:  # 模拟拼写错误
                    mock_tokens.append(MockToken(MockTokenType('IDENTIFIER'), word, 1, i*10))
            
            lexical_errors = corrector.analyze_lexical_errors(test_sql, mock_tokens)
            for error in lexical_errors:
                corrector.add_error(error)
        except Exception as e:
            pass
        
        # 模拟语法错误
        if "FORM" in test_sql:
            corrector.add_error(ErrorInfo(
                ErrorType.SPELLING, ErrorSeverity.WARNING,
                "可能的拼写错误: 'FORM' -> 'FROM'",
                1, test_sql.find("FORM") + 1, "FORM", ["FROM"]
            ))
        
        # 模拟语义错误
        if "UnknownTable" in test_sql:
            corrector.add_error(ErrorInfo(
                ErrorType.UNDEFINED_REFERENCE, ErrorSeverity.ERROR,
                "表 'UnknownTable' 不存在", 1, test_sql.find("UnknownTable") + 1,
                "UnknownTable", ["Students", "Teachers", "Courses"]
            ))
        
        # 生成修复建议
        suggestions = corrector.generate_correction_suggestions(test_sql, corrector.errors)
        for suggestion in suggestions:
            corrector.add_suggestion(suggestion)
        
        # 输出报告
        print(corrector.format_error_report())
        print(corrector.format_correction_suggestions())
        
        # 输出统计摘要
        summary = corrector.get_error_summary()
        print(f"错误统计: {summary['error_count']}个错误, {summary['warning_count']}个警告, {summary['suggestions_count']}个修复建议")


if __name__ == "__main__":
    main()
